🏠↩︎ De vuelta a la página principal del curso
🚀 Objetivo de la unidad
Que el estudiante sea capaz de importar y exportar bases de datos de y en diferentes formatos, así como ejecutar transformaciones básicas sobre estas utilizando data frames y el paquete data.table.
Nota importante: Los siguientes módulos prácticos son lineales.
# install.packages("ggplot2")
library(ggplot2)
Recuerde que un data frame se compone de vectores. En el siguiente bloque de código, se instancian dos vectores inicialmente,
x <- 1:10
y <- 3 + sin(x)
df <- data.frame(x=x, sin_of_x=y) # Los vectores que compondrán un data frame deben ser del mismo tamaño
La función head devuelve las primeras 6 observaciones (filas) de un data frame.
head(df)
## x sin_of_x
## 1 1 3.841471
## 2 2 3.909297
## 3 3 3.141120
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
La función tail devuelve las últimas 6 observaciones de un data frame.
tail(df)
## x sin_of_x
## 5 5 2.041076
## 6 6 2.720585
## 7 7 3.656987
## 8 8 3.989358
## 9 9 3.412118
## 10 10 2.455979
Tanto head() como tail(), pueden recibir el argumento adicional n, que indicará cuántas observaciones devuelvolverá.
tail(df, n=2) # Imprime las dos últimas observaciones
## x sin_of_x
## 9 9 3.412118
## 10 10 2.455979
La función colnames() devuelve los nombres de las variables de un data frame.
colnames(df)
## [1] "x" "sin_of_x"
La función length() devuelve el número de vectores que componen a un data frame. El número de vectores será entonces igual al número de variables (columnas).
length(df)
## [1] 2
La función dim() devuelve un vector de tamaño 2 con las dimensiones del data frame. En la primer posición del vector, se devolverá el número de observaciones, y en la segunda posición, el número de variables.
dim(df)
## [1] 10 2
Recuerde que un data frame es la versión bidimensional de una lista.
typeof(df)
## [1] "list"
La función str() devuelve el tipo y tamaño de cada vector que compone a un data frame. A esto se le conoce como la “estructura” de un data frame.
str(df)
## 'data.frame': 10 obs. of 2 variables:
## $ x : int 1 2 3 4 5 6 7 8 9 10
## $ sin_of_x: num 3.84 3.91 3.14 2.24 2.04 ...
La función summary() devuelve algunas de las medidas de dispersón de las variables numéricas de un data frame.
summary(df)
## x sin_of_x
## Min. : 1.00 Min. :2.041
## 1st Qu.: 3.25 1st Qu.:2.522
## Median : 5.50 Median :3.277
## Mean : 5.50 Mean :3.141
## 3rd Qu.: 7.75 3rd Qu.:3.795
## Max. :10.00 Max. :3.989
Recuerde cómo se veía nuestro data frame completo.
print(df)
## x sin_of_x
## 1 1 3.841471
## 2 2 3.909297
## 3 3 3.141120
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 7 7 3.656987
## 8 8 3.989358
## 9 9 3.412118
## 10 10 2.455979
Podemos extraer datos del data frame utilizando índices. En el siguiente caso, extraemos el dato de la variable #2 de la observación #1.
df[1, 2]
## [1] 3.841471
En el siguiente caso, extraemos el dato de la variable #2 de la observación #10.
df[10, 2]
## [1] 2.455979
Así mismo, podemos utilizar un vector de tamaño 1+n.
df[, 1:2]
## x sin_of_x
## 1 1 3.841471
## 2 2 3.909297
## 3 3 3.141120
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 7 7 3.656987
## 8 8 3.989358
## 9 9 3.412118
## 10 10 2.455979
df[c(3, 6), ]
## x sin_of_x
## 3 3 3.141120
## 6 6 2.720585
Podemos extraer observaciones completas.
df[10, ]
## x sin_of_x
## 10 10 2.455979
Podemos extraer el vector que compone una variable. En el siguiente caso, extraemos la variable #2.
df[, 2]
## [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
## [9] 3.412118 2.455979
También, podemos extraer el vector que compone una variable utilizando el nombre de la variable en lugar de su índice.
df[, "sin_of_x"]
## [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
## [9] 3.412118 2.455979
Finalmente, igual podemos extraer el vector que compone una variable utilizando $ + el nombre de la variable.
df$sin_of_x
## [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
## [9] 3.412118 2.455979
💡 He aquí la importancia de que los nombres de una variable no tengan espacios y utilicen guiones bajos.
Podemos extraer una variable conservando el formato de un data frame utilizando únicamente el índice o el nombre de la variable dentro de los corchetes:
df[2]
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
df["sin_of_x"]
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
Observe cómo la estructura cambia.
str(df[, 2]) # Este es un vector
## num [1:10] 3.84 3.91 3.14 2.24 2.04 ...
str(df[2]) # Este es un data frame
## 'data.frame': 10 obs. of 1 variable:
## $ sin_of_x: num 3.84 3.91 3.14 2.24 2.04 ...
La forma en que extraigamos el contenido de una variable, dependerá del uso que querramos darle. No existe una forma “correcta” de hacerlo.
De igual forma, podemos extraer variabes de un data frame con la función subset().
subset(df, select=sin_of_x)
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
subset(df, select=2)
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
No siempre sabremos el índice de las observaciones que queremos extraer de un data frame. En la mayoría de los casos, queremos extraer observaciones con base en una o varias condiciones.
df[df[, 2] < 3, ]
## x sin_of_x
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 10 10 2.455979
df[df[, "sin_of_x"] < 3, ]
## x sin_of_x
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 10 10 2.455979
df[df$sin < 3, ]
## x sin_of_x
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 10 10 2.455979
Para crear nuevas variables en un data frame, debemos asignar vectores nuevos vectores.
df$y <- 101:110 # Creamos una nueva variable asignándole la mu
print(df)
## x sin_of_x y
## 1 1 3.841471 101
## 2 2 3.909297 102
## 3 3 3.141120 103
## 4 4 2.243198 104
## 5 5 2.041076 105
## 6 6 2.720585 106
## 7 7 3.656987 107
## 8 8 3.989358 108
## 9 9 3.412118 109
## 10 10 2.455979 110
df$x_times_2 <- df$x * 2
print(df)
## x sin_of_x y x_times_2
## 1 1 3.841471 101 2
## 2 2 3.909297 102 4
## 3 3 3.141120 103 6
## 4 4 2.243198 104 8
## 5 5 2.041076 105 10
## 6 6 2.720585 106 12
## 7 7 3.656987 107 14
## 8 8 3.989358 108 16
## 9 9 3.412118 109 18
## 10 10 2.455979 110 20
df$x_times_2_flag <- df$x_times_2 > 10
print(df)
## x sin_of_x y x_times_2 x_times_2_flag
## 1 1 3.841471 101 2 FALSE
## 2 2 3.909297 102 4 FALSE
## 3 3 3.141120 103 6 FALSE
## 4 4 2.243198 104 8 FALSE
## 5 5 2.041076 105 10 FALSE
## 6 6 2.720585 106 12 TRUE
## 7 7 3.656987 107 14 TRUE
## 8 8 3.989358 108 16 TRUE
## 9 9 3.412118 109 18 TRUE
## 10 10 2.455979 110 20 TRUE
df$x_cat <- ifelse(df$x == 2, yes="x igual a 2", no="x no es igual a dos")
print(df)
## x sin_of_x y x_times_2 x_times_2_flag x_cat
## 1 1 3.841471 101 2 FALSE x no es igual a dos
## 2 2 3.909297 102 4 FALSE x igual a 2
## 3 3 3.141120 103 6 FALSE x no es igual a dos
## 4 4 2.243198 104 8 FALSE x no es igual a dos
## 5 5 2.041076 105 10 FALSE x no es igual a dos
## 6 6 2.720585 106 12 TRUE x no es igual a dos
## 7 7 3.656987 107 14 TRUE x no es igual a dos
## 8 8 3.989358 108 16 TRUE x no es igual a dos
## 9 9 3.412118 109 18 TRUE x no es igual a dos
## 10 10 2.455979 110 20 TRUE x no es igual a dos
Utilice el data frame construído en el ejercicio #2.
df_txt <- read.table("./data/plain_txt.txt",
header = FALSE)
## Warning in read.table("./data/plain_txt.txt", header = FALSE): incomplete final
## line found by readTableHeader on './data/plain_txt.txt'
df_csv <- read.csv("./data/plain_csv.csv")
## Warning in read.table(file = file, header = header, sep = sep, quote = quote, :
## incomplete final line found by readTableHeader on './data/plain_csv.csv'
df_delim <- read.delim("./data/txt_with_delim.txt", sep="$")
## Warning in read.table(file = file, header = header, sep = sep, quote = quote, :
## incomplete final line found by readTableHeader on './data/txt_with_delim.txt'
library(readxl)
df_xlsx <- read_xlsx("./data/hoja_de_calculo.xlsx", sheet=1)
library(foreign)
# df_spss <- read.spss("example.sav",
# to.data.frame=TRUE,
# use.value.labels=FALSE) # SPSS data
# df_stata <- read.dta("example.dta") # Stata data
# file_url <- "https://data.cityofnewyork.us/api/views/kku6-nxdu/rows.csv?accessType=DOWNLOAD"
# download.file(file_url, destfile = "./data/demo_nyc.csv", method = "curl")
df_Demographic <- read.csv("./data/demo_nyc.csv")
Se recomienda ampliamente únicamente importar datos en formato csv.
# write.csv(df, file = ".data/cards.csv", row.names = FALSE)
print(df_delim)
## Col1 Col2 Col3
## 1 1 2 3
## 2 4 5 6
## 3 7 8 9
## 4 a b c
print(df_xlsx)
## # A tibble: 5 x 2
## x1 x2
## <dbl> <dbl>
## 1 1 2
## 2 2 4
## 3 3 6
## 4 4 8
## 5 5 10
merged_df <- merge(x = df_delim, # x
y = df_xlsx, # y
by.x = "Col1", # Llave en x
by.y = "x1", # Llave en y
all.x = T) # Conserva todas los elementos de x
print(merged_df)
## Col1 Col2 Col3 x2
## 1 1 2 3 2
## 2 4 5 6 8
## 3 7 8 9 NA
## 4 a b c NA
merged_df <- merge(x = df_delim, # x
y = df_xlsx, # y
by.x = "Col1", # Llave en x
by.y = "x1", # Llave en y
all.y = T) # Conserva todas los elementos de x
print(merged_df)
## Col1 Col2 Col3 x2
## 1 1 2 3 2
## 2 2 <NA> <NA> 4
## 3 3 <NA> <NA> 6
## 4 4 5 6 8
## 5 5 <NA> <NA> 10
Instalando y cargando el paquete data.table.
# install.packages("data.table")
library(data.table)
Para leer archivos utilizamos la función fread().
dt_Demographic <- fread("./data/demo_nyc.csv")
str(dt_Demographic)
## Classes 'data.table' and 'data.frame': 236 obs. of 46 variables:
## $ JURISDICTION NAME : int 10001 10002 10003 10004 10005 10006 10007 10009 10010 10011 ...
## $ COUNT PARTICIPANTS : int 44 35 1 0 2 6 1 2 0 3 ...
## $ COUNT FEMALE : int 22 19 1 0 2 2 0 0 0 2 ...
## $ PERCENT FEMALE : num 0.5 0.54 1 0 1 0.33 0 0 0 0.67 ...
## $ COUNT MALE : int 22 16 0 0 0 4 1 2 0 1 ...
## $ PERCENT MALE : num 0.5 0.46 0 0 0 0.67 1 1 0 0.33 ...
## $ COUNT GENDER UNKNOWN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERCENT GENDER UNKNOWN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNT GENDER TOTAL : int 44 35 1 0 2 6 1 2 0 3 ...
## $ PERCENT GENDER TOTAL : int 100 100 100 0 100 100 100 100 0 100 ...
## $ COUNT PACIFIC ISLANDER : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERCENT PACIFIC ISLANDER : num 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNT HISPANIC LATINO : int 16 1 0 0 0 2 0 0 0 1 ...
## $ PERCENT HISPANIC LATINO : num 0.36 0.03 0 0 0 0.33 0 0 0 0.33 ...
## $ COUNT AMERICAN INDIAN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERCENT AMERICAN INDIAN : num 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNT ASIAN NON HISPANIC : int 3 28 1 0 1 0 1 2 0 0 ...
## $ PERCENT ASIAN NON HISPANIC : num 0.07 0.8 1 0 0.5 0 1 1 0 0 ...
## $ COUNT WHITE NON HISPANIC : int 1 6 0 0 0 1 0 0 0 0 ...
## $ PERCENT WHITE NON HISPANIC : num 0.02 0.17 0 0 0 0.17 0 0 0 0 ...
## $ COUNT BLACK NON HISPANIC : int 21 0 0 0 1 3 0 0 0 1 ...
## $ PERCENT BLACK NON HISPANIC : num 0.48 0 0 0 0.5 0.5 0 0 0 0.33 ...
## $ COUNT OTHER ETHNICITY : int 3 0 0 0 0 0 0 0 0 1 ...
## $ PERCENT OTHER ETHNICITY : num 0.07 0 0 0 0 0 0 0 0 0.33 ...
## $ COUNT ETHNICITY UNKNOWN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERCENT ETHNICITY UNKNOWN : num 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNT ETHNICITY TOTAL : int 44 35 1 0 2 6 1 2 0 3 ...
## $ PERCENT ETHNICITY TOTAL : int 100 100 100 0 100 100 100 100 0 99 ...
## $ COUNT PERMANENT RESIDENT ALIEN : int 2 2 0 0 1 0 0 0 0 0 ...
## $ PERCENT PERMANENT RESIDENT ALIEN : num 0.05 0.06 0 0 0.5 0 0 0 0 0 ...
## $ COUNT US CITIZEN : int 42 33 1 0 1 6 1 2 0 3 ...
## $ PERCENT US CITIZEN : num 0.95 0.94 1 0 0.5 1 1 1 0 1 ...
## $ COUNT OTHER CITIZEN STATUS : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERCENT OTHER CITIZEN STATUS : num 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNT CITIZEN STATUS UNKNOWN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERCENT CITIZEN STATUS UNKNOWN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNT CITIZEN STATUS TOTAL : int 44 35 1 0 2 6 1 2 0 3 ...
## $ PERCENT CITIZEN STATUS TOTAL : int 100 100 100 0 100 100 100 100 0 100 ...
## $ COUNT RECEIVES PUBLIC ASSISTANCE : int 20 2 0 0 0 0 1 0 0 0 ...
## $ PERCENT RECEIVES PUBLIC ASSISTANCE : num 0.45 0.06 0 0 0 0 1 0 0 0 ...
## $ COUNT NRECEIVES PUBLIC ASSISTANCE : int 24 33 1 0 2 6 0 2 0 3 ...
## $ PERCENT NRECEIVES PUBLIC ASSISTANCE: num 0.55 0.94 1 0 1 1 0 1 0 1 ...
## $ COUNT PUBLIC ASSISTANCE UNKNOWN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ PERCENT PUBLIC ASSISTANCE UNKNOWN : int 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNT PUBLIC ASSISTANCE TOTAL : int 44 35 1 0 2 6 1 2 0 3 ...
## $ PERCENT PUBLIC ASSISTANCE TOTAL : int 100 100 100 0 100 100 100 100 0 100 ...
## - attr(*, ".internal.selfref")=<externalptr>
setnames() es una función que nos permitirá cambiar los nombres de columna de un data.table de forma “segura”.
setnames(dt_Demographic, old = "COUNT FEMALE", new = "COUNT_FEMALE")
colnames(dt_Demographic)
## [1] "JURISDICTION NAME" "COUNT PARTICIPANTS"
## [3] "COUNT_FEMALE" "PERCENT FEMALE"
## [5] "COUNT MALE" "PERCENT MALE"
## [7] "COUNT GENDER UNKNOWN" "PERCENT GENDER UNKNOWN"
## [9] "COUNT GENDER TOTAL" "PERCENT GENDER TOTAL"
## [11] "COUNT PACIFIC ISLANDER" "PERCENT PACIFIC ISLANDER"
## [13] "COUNT HISPANIC LATINO" "PERCENT HISPANIC LATINO"
## [15] "COUNT AMERICAN INDIAN" "PERCENT AMERICAN INDIAN"
## [17] "COUNT ASIAN NON HISPANIC" "PERCENT ASIAN NON HISPANIC"
## [19] "COUNT WHITE NON HISPANIC" "PERCENT WHITE NON HISPANIC"
## [21] "COUNT BLACK NON HISPANIC" "PERCENT BLACK NON HISPANIC"
## [23] "COUNT OTHER ETHNICITY" "PERCENT OTHER ETHNICITY"
## [25] "COUNT ETHNICITY UNKNOWN" "PERCENT ETHNICITY UNKNOWN"
## [27] "COUNT ETHNICITY TOTAL" "PERCENT ETHNICITY TOTAL"
## [29] "COUNT PERMANENT RESIDENT ALIEN" "PERCENT PERMANENT RESIDENT ALIEN"
## [31] "COUNT US CITIZEN" "PERCENT US CITIZEN"
## [33] "COUNT OTHER CITIZEN STATUS" "PERCENT OTHER CITIZEN STATUS"
## [35] "COUNT CITIZEN STATUS UNKNOWN" "PERCENT CITIZEN STATUS UNKNOWN"
## [37] "COUNT CITIZEN STATUS TOTAL" "PERCENT CITIZEN STATUS TOTAL"
## [39] "COUNT RECEIVES PUBLIC ASSISTANCE" "PERCENT RECEIVES PUBLIC ASSISTANCE"
## [41] "COUNT NRECEIVES PUBLIC ASSISTANCE" "PERCENT NRECEIVES PUBLIC ASSISTANCE"
## [43] "COUNT PUBLIC ASSISTANCE UNKNOWN" "PERCENT PUBLIC ASSISTANCE UNKNOWN"
## [45] "COUNT PUBLIC ASSISTANCE TOTAL" "PERCENT PUBLIC ASSISTANCE TOTAL"
setnames(dt_Demographic,
old = colnames(dt_Demographic),
new = gsub(" ", "_", colnames(dt_Demographic)))
colnames(dt_Demographic)
## [1] "JURISDICTION_NAME" "COUNT_PARTICIPANTS"
## [3] "COUNT_FEMALE" "PERCENT_FEMALE"
## [5] "COUNT_MALE" "PERCENT_MALE"
## [7] "COUNT_GENDER_UNKNOWN" "PERCENT_GENDER_UNKNOWN"
## [9] "COUNT_GENDER_TOTAL" "PERCENT_GENDER_TOTAL"
## [11] "COUNT_PACIFIC_ISLANDER" "PERCENT_PACIFIC_ISLANDER"
## [13] "COUNT_HISPANIC_LATINO" "PERCENT_HISPANIC_LATINO"
## [15] "COUNT_AMERICAN_INDIAN" "PERCENT_AMERICAN_INDIAN"
## [17] "COUNT_ASIAN_NON_HISPANIC" "PERCENT_ASIAN_NON_HISPANIC"
## [19] "COUNT_WHITE_NON_HISPANIC" "PERCENT_WHITE_NON_HISPANIC"
## [21] "COUNT_BLACK_NON_HISPANIC" "PERCENT_BLACK_NON_HISPANIC"
## [23] "COUNT_OTHER_ETHNICITY" "PERCENT_OTHER_ETHNICITY"
## [25] "COUNT_ETHNICITY_UNKNOWN" "PERCENT_ETHNICITY_UNKNOWN"
## [27] "COUNT_ETHNICITY_TOTAL" "PERCENT_ETHNICITY_TOTAL"
## [29] "COUNT_PERMANENT_RESIDENT_ALIEN" "PERCENT_PERMANENT_RESIDENT_ALIEN"
## [31] "COUNT_US_CITIZEN" "PERCENT_US_CITIZEN"
## [33] "COUNT_OTHER_CITIZEN_STATUS" "PERCENT_OTHER_CITIZEN_STATUS"
## [35] "COUNT_CITIZEN_STATUS_UNKNOWN" "PERCENT_CITIZEN_STATUS_UNKNOWN"
## [37] "COUNT_CITIZEN_STATUS_TOTAL" "PERCENT_CITIZEN_STATUS_TOTAL"
## [39] "COUNT_RECEIVES_PUBLIC_ASSISTANCE" "PERCENT_RECEIVES_PUBLIC_ASSISTANCE"
## [41] "COUNT_NRECEIVES_PUBLIC_ASSISTANCE" "PERCENT_NRECEIVES_PUBLIC_ASSISTANCE"
## [43] "COUNT_PUBLIC_ASSISTANCE_UNKNOWN" "PERCENT_PUBLIC_ASSISTANCE_UNKNOWN"
## [45] "COUNT_PUBLIC_ASSISTANCE_TOTAL" "PERCENT_PUBLIC_ASSISTANCE_TOTAL"
Seleccionando observaciones con i.
# head(dt_Demographic[1:2, ])
# head(dt_Demographic[COUNT_FEMALE > 50, ])
Ordenando con i.
# head(dt_Demographic[order(COUNT_PARTICIPANTS), ])
# head(dt_Demographic[order(JURISDICTION_NAME), ])
# head(dt_Demographic[order(-JURISDICTION_NAME), ])
Seleccionando columnas con j.
# head(dt_Demographic[, .(JURISDICTION_NAME, COUNT_US_CITIZEN)])
# head(dt_Demographic[, c("JURISDICTION_NAME", "COUNT_US_CITIZEN")])
Operando con columnas j.
dt_Demographic[, .(mean(COUNT_FEMALE))]
## V1
## 1: 10.29661
dt_Demographic[, .(mean(COUNT_FEMALE), mean(COUNT_MALE), sum(COUNT_FEMALE), sum(COUNT_MALE))]
## V1 V2 V3 V4
## 1: 10.29661 7.364407 2430 1738
dt_Demographic[, .N] # .N es un conteo de observaciones
## [1] 236
Renombrando las operaciones con columnas j.
dt_Demographic[, .(prom_fem = mean(COUNT_FEMALE), n_fem = sum(COUNT_FEMALE))]
## prom_fem n_fem
## 1: 10.29661 2430
dt_Demographic[, .(n_fem = .N)]
## n_fem
## 1: 236
Seleccionando columnas con k.